﻿

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Globalization;
using System.Windows.Forms;
using AntdUI;
using ChineseCalendar;

namespace AttendanceSysytem.Controls;

//
// 摘要:
//     CalendarEx 日历
//
// 言论：
//     按照日历形式展示数据的容器。
[Description("CalendarEx 日历")]
[ToolboxItem(true)]
[DefaultProperty("Date")]
[DefaultEvent("DateChanged")]
public class CalendarEx : IControl
{
    private int radius = 6;

    private bool full;

    private bool chinese;

    private bool showButtonToDay = true;

    private Dictionary<string, DateBadgeEx> badge_list = new Dictionary<string, DateBadgeEx>();

    //
    // 摘要:
    //     日期徽标回调
    public Func<DateTime[], List<DateBadgeEx>?>? BadgeAction;

    private List<Calendari>? calendar_year;

    private List<Calendari>? calendar_month;

    private List<Calendari>? calendar_day;

    private DateTime _value = DateTime.Now;

    private DateTime? minDate;

    private DateTime? maxDate;

    private DateTime _Date;

    private DateTime DateNow = DateTime.Now;

    private string year_str = "";

    private CultureInfo Culture;

    private string CultureID = Localization.Get("ID", "zh-CN");

    private string button_text = Localization.Get("ToDay", "今天");

    private string OKButton = Localization.Get("OK", "确定");

    private string YearFormat;

    private string MonthFormat;

    private string MondayButton;

    private string TuesdayButton;

    private string WednesdayButton;

    private string ThursdayButton;

    private string FridayButton;

    private string SaturdayButton;

    private string SundayButton;

    private bool YDR;

    private StringFormat s_f = Helper.SF();

    private StringFormat s_f_L;

    private StringFormat s_f_R;

    private Rectangle rect_year_l;

    private Rectangle rect_month_l;

    private RectangleF rect_day_split1;

    private RectangleF rect_day_split2;

    private Rectangle[]? rect_day_s;

    private ITaskOpacity hover_button;

    private ITaskOpacity hover_lefts;

    private ITaskOpacity hover_left;

    private ITaskOpacity hover_rights;

    private ITaskOpacity hover_right;

    private ITaskOpacity hover_year;

    private ITaskOpacity hover_month;

    private Rectangle rect_button = new Rectangle(-20, -20, 10, 10);

    private Rectangle rect_lefts = new Rectangle(-20, -20, 10, 10);

    private Rectangle rect_left = new Rectangle(-20, -20, 10, 10);

    private Rectangle rect_rights = new Rectangle(-20, -20, 10, 10);

    private Rectangle rect_right = new Rectangle(-20, -20, 10, 10);

    private Rectangle rect_year = new Rectangle(-20, -20, 10, 10);

    private Rectangle rect_year2 = new Rectangle(-20, -20, 10, 10);

    private Rectangle rect_month = new Rectangle(-20, -20, 10, 10);

    private int showType;

    //
    // 摘要:
    //     圆角
    [Description("圆角")]
    [Category("外观")]
    [DefaultValue(6)]
    public int Radius
    {
        get
        {
            return radius;
        }
        set
        {
            if (radius != value)
            {
                radius = value;
                Invalidate();
            }
        }
    }

    //
    // 摘要:
    //     是否撑满
    [Description("是否撑满")]
    [Category("外观")]
    [DefaultValue(false)]
    public bool Full
    {
        get
        {
            return full;
        }
        set
        {
            if (full != value)
            {
                full = value;
                OnSizeChanged(EventArgs.Empty);
                Invalidate();
            }
        }
    }

    //
    // 摘要:
    //     显示农历
    [Description("显示农历")]
    [Category("外观")]
    [DefaultValue(false)]
    public bool ShowChinese
    {
        get
        {
            return chinese;
        }
        set
        {
            if (chinese != value)
            {
                chinese = value;
                OnSizeChanged(EventArgs.Empty);
                Invalidate();
            }
        }
    }

    //
    // 摘要:
    //     显示今天
    [Description("显示今天")]
    [Category("外观")]
    [DefaultValue(true)]
    public bool ShowButtonToDay
    {
        get
        {
            return showButtonToDay;
        }
        set
        {
            if (showButtonToDay != value)
            {
                showButtonToDay = value;
                OnSizeChanged(EventArgs.Empty);
                Invalidate();
            }
        }
    }

    //
    // 摘要:
    //     控件当前日期
    [Description("控件当前日期")]
    [Category("数据")]
    [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
    public DateTime Value
    {
        get
        {
            return _value;
        }
        set
        {
            _value = value;
            this.DateChanged?.Invoke(this, new DateTimeEventArgs(_value));
            Invalidate();
            LoadBadge();
        }
    }

    //
    // 摘要:
    //     最小日期
    [Description("最小日期")]
    [Category("数据")]
    [DefaultValue(null)]
    public DateTime? MinDate
    {
        get
        {
            return minDate;
        }
        set
        {
            if (!(minDate == value))
            {
                minDate = value;
                Date = _Date;
                Invalidate();
            }
        }
    }

    //
    // 摘要:
    //     最大日期
    [Description("最大日期")]
    [Category("数据")]
    [DefaultValue(null)]
    public DateTime? MaxDate
    {
        get
        {
            return maxDate;
        }
        set
        {
            if (!(maxDate == value))
            {
                maxDate = value;
                Date = _Date;
                Invalidate();
            }
        }
    }

    private DateTime Date
    {
        get
        {
            return _Date;
        }
        set
        {
            _Date = value;
            calendar_day = GetCalendar(value);
            List<Calendari> list = new List<Calendari>(12);
            int num = 0;
            int num2 = 0;
            for (int i = 0; i < 12; i++)
            {
                DateTime date = new DateTime(value.Year, i + 1, 1);
                list.Add(new Calendari(0, num, num2, date.ToString(MonthFormat, Culture), date, date.ToString("yyyy-MM"), minDate, maxDate));
                num++;
                if (num > 2)
                {
                    num2++;
                    num = 0;
                }
            }

            calendar_month = list;
            int num3 = value.Year - 1;
            if (!value.Year.ToString().EndsWith("0"))
            {
                string text = value.Year.ToString();
                num3 = int.Parse(text.Substring(0, text.Length - 1) + "0") - 1;
            }

            List<Calendari> list2 = new List<Calendari>(12);
            int num4 = 0;
            int num5 = 0;
            if (num3 < 1)
            {
                num3 = 1;
            }

            for (int j = 0; j < 12; j++)
            {
                DateTime date2 = new DateTime(num3 + j, value.Month, 1);
                list2.Add(new Calendari((j != 0) ? 1 : 0, num4, num5, date2.ToString("yyyy"), date2, date2.ToString("yyyy"), minDate, maxDate));
                num4++;
                if (num4 > 2)
                {
                    num5++;
                    num4 = 0;
                }
            }

            year_str = list2[1].date_str + "-" + list2[list2.Count - 2].date_str;
            calendar_year = list2;
            OnSizeChanged(EventArgs.Empty);
            LoadBadge();
            hover_left.Enable = Helper.DateExceed(value.AddMonths(-1), minDate, maxDate);
            hover_right.Enable = Helper.DateExceed(value.AddMonths(1), minDate, maxDate);
            hover_lefts.Enable = Helper.DateExceed(value.AddYears(-1), minDate, maxDate);
            hover_rights.Enable = Helper.DateExceed(value.AddYears(1), minDate, maxDate);
        }
    }

    public override Rectangle ReadRectangle => base.ClientRectangle.PaddingRect(base.Padding);

    public override GraphicsPath RenderRegion
    {
        get
        {
            Rectangle readRectangle = ReadRectangle;
            float num = (float)radius * Config.Dpi;
            return readRectangle.RoundPath(num);
        }
    }

    [Description("日期 改变时发生")]
    [Category("行为")]
    public event DateTimeEventHandler? DateChanged;

    public CalendarEx()
    {
        hover_lefts = new ITaskOpacity(this);
        hover_left = new ITaskOpacity(this);
        hover_rights = new ITaskOpacity(this);
        hover_right = new ITaskOpacity(this);
        hover_year = new ITaskOpacity(this);
        hover_month = new ITaskOpacity(this);
        hover_button = new ITaskOpacity(this);
        Date = DateNow;
        Culture = new CultureInfo(CultureID);
        YDR = CultureID.StartsWith("en");
        if (YDR)
        {
            YearFormat = "yyyy";
            MonthFormat = "MMM";
            MondayButton = "Mon";
            TuesdayButton = "Tue";
            WednesdayButton = "Wed";
            ThursdayButton = "Thu";
            FridayButton = "Fri";
            SaturdayButton = "Sat";
            SundayButton = "Sun";
            s_f_L = Helper.SF(StringAlignment.Center, StringAlignment.Near);
            s_f_R = Helper.SF(StringAlignment.Center, StringAlignment.Far);
        }
        else
        {
            YearFormat = "yyyy年";
            MonthFormat = "MM月";
            MondayButton = "一";
            TuesdayButton = "二";
            WednesdayButton = "三";
            ThursdayButton = "四";
            FridayButton = "五";
            SaturdayButton = "六";
            SundayButton = "日";
            s_f_L = Helper.SF(StringAlignment.Center, StringAlignment.Far);
            s_f_R = Helper.SF(StringAlignment.Center, StringAlignment.Near);
        }
    }

    private List<Calendari> GetCalendar(DateTime now)
    {
        List<Calendari> list = new List<Calendari>(28);
        int num = DateTime.DaysInMonth(now.Year, now.Month);
        DateTime dateTime = new DateTime(now.Year, now.Month, 1);
        int num2 = 0;
        switch (dateTime.DayOfWeek)
        {
            case DayOfWeek.Tuesday:
                num2 = 1;
                break;
            case DayOfWeek.Wednesday:
                num2 = 2;
                break;
            case DayOfWeek.Thursday:
                num2 = 3;
                break;
            case DayOfWeek.Friday:
                num2 = 4;
                break;
            case DayOfWeek.Saturday:
                num2 = 5;
                break;
            case DayOfWeek.Sunday:
                num2 = 6;
                break;
        }

        if (num2 > 0)
        {
            DateTime dateTime2 = now.AddMonths(-1);
            int num3 = DateTime.DaysInMonth(dateTime2.Year, dateTime2.Month);
            for (int i = 0; i < num2; i++)
            {
                int day = num3 - i;
                list.Insert(0, new Calendari(0, num2 - 1 - i, 0, day.ToString(), new DateTime(dateTime2.Year, dateTime2.Month, day), minDate, maxDate));
            }
        }

        int num4 = num2;
        int num5 = 0;
        for (int j = 0; j < num; j++)
        {
            int day2 = j + 1;
            list.Add(new Calendari(1, num4, num5, day2.ToString(), new DateTime(now.Year, now.Month, day2), minDate, maxDate));
            num4++;
            if (num4 > 6)
            {
                num5++;
                num4 = 0;
            }
        }

        if (num4 < 7)
        {
            DateTime dateTime3 = now.AddMonths(1);
            int num6 = 0;
            for (int k = num4; k < 7; k++)
            {
                int day3 = num6 + 1;
                list.Add(new Calendari(2, num4, num5, day3.ToString(), new DateTime(dateTime3.Year, dateTime3.Month, day3), minDate, maxDate));
                num4++;
                num6++;
            }

            if (num5 < 5)
            {
                num5++;
                for (int l = 0; l < 7; l++)
                {
                    int day4 = num6 + 1;
                    list.Add(new Calendari(2, l, num5, day4.ToString(), new DateTime(dateTime3.Year, dateTime3.Month, day4), minDate, maxDate));
                    num6++;
                }
            }
        }

        return list;
    }

    //
    // 摘要:
    //     加载徽标
    public void LoadBadge()
    {
        if (BadgeAction == null || calendar_day == null)
        {
            return;
        }

        DateTime oldval = _Date;
        ITask.Run(delegate
        {
            List<DateBadgeEx> list = BadgeAction(new DateTime[2]
            {
                calendar_day[0].date,
                calendar_day[calendar_day.Count - 1].date
            });
            if (_Date == oldval)
            {
                badge_list.Clear();
                if (list == null)
                {
                    Invalidate();
                }
                else
                {
                    foreach (DateBadgeEx item in list)
                    {
                        badge_list.Add(item.Date, item);
                    }

                    Invalidate();
                }
            }
        }).Wait();
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        Canvas canvas = e.Graphics.High();
        _ = base.ClientRectangle;
        Rectangle readRectangle = ReadRectangle;
        using (GraphicsPath path = readRectangle.RoundPath((float)radius * Config.Dpi))
        {
            canvas.Fill(Style.Db.BgElevated, path);
        }

        using (Pen pen = new Pen(Style.Db.TextTertiary, 1.6f * Config.Dpi))
        {
            using Pen pen2 = new Pen(Style.Db.Text, pen.Width);
            using Pen pen4 = new Pen(Style.Db.FillSecondary, pen.Width);
            if (hover_lefts.Animation)
            {
                using Pen pen3 = new Pen(pen.Color.BlendColors(hover_lefts.Value, pen2.Color), pen2.Width);
                canvas.DrawLines(pen3, TAlignMini.Left.TriangleLines(new Rectangle(rect_lefts.X - 4, rect_lefts.Y, rect_lefts.Width, rect_lefts.Height), 0.26f));
                canvas.DrawLines(pen3, TAlignMini.Left.TriangleLines(new Rectangle(rect_lefts.X + 4, rect_lefts.Y, rect_lefts.Width, rect_lefts.Height), 0.26f));
            }
            else if (hover_lefts.Switch)
            {
                canvas.DrawLines(pen2, TAlignMini.Left.TriangleLines(new Rectangle(rect_lefts.X - 4, rect_lefts.Y, rect_lefts.Width, rect_lefts.Height), 0.26f));
                canvas.DrawLines(pen2, TAlignMini.Left.TriangleLines(new Rectangle(rect_lefts.X + 4, rect_lefts.Y, rect_lefts.Width, rect_lefts.Height), 0.26f));
            }
            else if (hover_lefts.Enable)
            {
                canvas.DrawLines(pen, TAlignMini.Left.TriangleLines(new Rectangle(rect_lefts.X - 4, rect_lefts.Y, rect_lefts.Width, rect_lefts.Height), 0.26f));
                canvas.DrawLines(pen, TAlignMini.Left.TriangleLines(new Rectangle(rect_lefts.X + 4, rect_lefts.Y, rect_lefts.Width, rect_lefts.Height), 0.26f));
            }
            else
            {
                canvas.DrawLines(pen4, TAlignMini.Left.TriangleLines(new Rectangle(rect_lefts.X - 4, rect_lefts.Y, rect_lefts.Width, rect_lefts.Height), 0.26f));
                canvas.DrawLines(pen4, TAlignMini.Left.TriangleLines(new Rectangle(rect_lefts.X + 4, rect_lefts.Y, rect_lefts.Width, rect_lefts.Height), 0.26f));
            }

            if (hover_rights.Animation)
            {
                using Pen pen5 = new Pen(pen.Color.BlendColors(hover_rights.Value, pen2.Color), pen2.Width);
                canvas.DrawLines(pen5, TAlignMini.Right.TriangleLines(new Rectangle(rect_rights.X - 4, rect_rights.Y, rect_rights.Width, rect_rights.Height), 0.26f));
                canvas.DrawLines(pen5, TAlignMini.Right.TriangleLines(new Rectangle(rect_rights.X + 4, rect_rights.Y, rect_rights.Width, rect_rights.Height), 0.26f));
            }
            else if (hover_rights.Switch)
            {
                canvas.DrawLines(pen2, TAlignMini.Right.TriangleLines(new Rectangle(rect_rights.X - 4, rect_rights.Y, rect_rights.Width, rect_rights.Height), 0.26f));
                canvas.DrawLines(pen2, TAlignMini.Right.TriangleLines(new Rectangle(rect_rights.X + 4, rect_rights.Y, rect_rights.Width, rect_rights.Height), 0.26f));
            }
            else if (hover_rights.Enable)
            {
                canvas.DrawLines(pen, TAlignMini.Right.TriangleLines(new Rectangle(rect_rights.X - 4, rect_rights.Y, rect_rights.Width, rect_rights.Height), 0.26f));
                canvas.DrawLines(pen, TAlignMini.Right.TriangleLines(new Rectangle(rect_rights.X + 4, rect_rights.Y, rect_rights.Width, rect_rights.Height), 0.26f));
            }
            else
            {
                canvas.DrawLines(pen4, TAlignMini.Right.TriangleLines(new Rectangle(rect_rights.X - 4, rect_rights.Y, rect_rights.Width, rect_rights.Height), 0.26f));
                canvas.DrawLines(pen4, TAlignMini.Right.TriangleLines(new Rectangle(rect_rights.X + 4, rect_rights.Y, rect_rights.Width, rect_rights.Height), 0.26f));
            }

            if (showType == 0)
            {
                if (hover_left.Animation)
                {
                    using Pen pen6 = new Pen(pen.Color.BlendColors(hover_left.Value, pen2.Color), pen2.Width);
                    canvas.DrawLines(pen6, TAlignMini.Left.TriangleLines(rect_left, 0.26f));
                }
                else if (hover_left.Switch)
                {
                    canvas.DrawLines(pen2, TAlignMini.Left.TriangleLines(rect_left, 0.26f));
                }
                else if (hover_left.Enable)
                {
                    canvas.DrawLines(pen, TAlignMini.Left.TriangleLines(rect_left, 0.26f));
                }
                else
                {
                    canvas.DrawLines(pen4, TAlignMini.Left.TriangleLines(rect_left, 0.26f));
                }

                if (hover_right.Animation)
                {
                    using Pen pen7 = new Pen(pen.Color.BlendColors(hover_right.Value, pen2.Color), pen2.Width);
                    canvas.DrawLines(pen7, TAlignMini.Right.TriangleLines(rect_right, 0.26f));
                }
                else if (hover_right.Switch)
                {
                    canvas.DrawLines(pen2, TAlignMini.Right.TriangleLines(rect_right, 0.26f));
                }
                else if (hover_right.Enable)
                {
                    canvas.DrawLines(pen, TAlignMini.Right.TriangleLines(rect_right, 0.26f));
                }
                else
                {
                    canvas.DrawLines(pen4, TAlignMini.Right.TriangleLines(rect_right, 0.26f));
                }
            }
        }

        if (showType == 1 && calendar_month != null)
        {
            PrintMonth(canvas, readRectangle, radius, calendar_month);
        }
        else if (showType == 2 && calendar_year != null)
        {
            PrintYear(canvas, readRectangle, radius, calendar_year);
        }
        else if (calendar_day != null)
        {
            PrintDay(canvas, readRectangle, radius, calendar_day);
        }

        this.PaintBadge(canvas);
        base.OnPaint(e);
    }

    //
    // 摘要:
    //     渲染年模式
    //
    // 参数:
    //   g:
    //     GDI
    //
    //   rect_read:
    //     真实区域
    //
    //   datas:
    //     数据
    private void PrintYear(Canvas g, Rectangle rect_read, float radius, List<Calendari> datas)
    {
        Color textBase = Style.Db.TextBase;
        using (Font font = new Font(Font.FontFamily, Font.Size, FontStyle.Bold))
        {
            if (hover_year.Animation)
            {
                g.String(year_str, font, textBase.BlendColors(hover_year.Value, Style.Db.Primary), rect_year_l, s_f);
            }
            else if (hover_year.Switch)
            {
                g.String(year_str, font, Style.Db.Primary, rect_year_l, s_f);
            }
            else
            {
                g.String(year_str, font, textBase, rect_year_l, s_f);
            }
        }

        using SolidBrush solidBrush2 = new SolidBrush(Style.Db.TextQuaternary);
        using SolidBrush brush = new SolidBrush(Style.Db.FillTertiary);
        using SolidBrush solidBrush = new SolidBrush(textBase);
        foreach (Calendari data in datas)
        {
            using GraphicsPath path = data.rect_read.RoundPath(radius);
            if (_value.ToString("yyyy") == data.date_str)
            {
                g.Fill(Style.Db.Primary, path);
                g.String(data.v, Font, Style.Db.PrimaryColor, data.rect, s_f);
            }
            else if (data.enable)
            {
                if (data.hover)
                {
                    g.Fill(Style.Db.FillTertiary, path);
                }

                if (DateNow.ToString("yyyy-MM-dd") == data.date_str)
                {
                    g.Draw(Style.Db.Primary, Config.Dpi, path);
                }

                g.String(data.v, Font, (data.t == 1) ? solidBrush : solidBrush2, data.rect, s_f);
            }
            else
            {
                g.Fill(brush, new Rectangle(data.rect.X, data.rect_read.Y, data.rect.Width, data.rect_read.Height));
                if (DateNow.ToString("yyyy-MM-dd") == data.date_str)
                {
                    g.Draw(Style.Db.Primary, Config.Dpi, path);
                }

                g.String(data.v, Font, solidBrush2, data.rect, s_f);
            }
        }
    }

    //
    // 摘要:
    //     渲染月模式
    //
    // 参数:
    //   g:
    //     GDI
    //
    //   rect_read:
    //     真实区域
    //
    //   datas:
    //     数据
    private void PrintMonth(Canvas g, Rectangle rect_read, float radius, List<Calendari> datas)
    {
        Color textBase = Style.Db.TextBase;
        using (Font font = new Font(Font.FontFamily, Font.Size, FontStyle.Bold))
        {
            string text = _Date.ToString(YearFormat, Culture);
            if (hover_year.Animation)
            {
                g.String(text, font, textBase.BlendColors(hover_year.Value, Style.Db.Primary), rect_month_l, s_f);
            }
            else if (hover_year.Switch)
            {
                g.String(text, font, Style.Db.Primary, rect_month_l, s_f);
            }
            else
            {
                g.String(text, font, textBase, rect_month_l, s_f);
            }
        }

        using SolidBrush brush3 = new SolidBrush(Style.Db.TextQuaternary);
        using SolidBrush brush2 = new SolidBrush(Style.Db.FillTertiary);
        using SolidBrush brush = new SolidBrush(textBase);
        foreach (Calendari data in datas)
        {
            using GraphicsPath path = data.rect_read.RoundPath(radius);
            if (_value.ToString("yyyy-MM") == data.date_str)
            {
                g.Fill(Style.Db.Primary, path);
                g.String(data.v, Font, Style.Db.PrimaryColor, data.rect, s_f);
            }
            else if (data.enable)
            {
                if (data.hover)
                {
                    g.Fill(Style.Db.FillTertiary, path);
                }

                if (DateNow.ToString("yyyy-MM-dd") == data.date_str)
                {
                    g.Draw(Style.Db.Primary, Config.Dpi, path);
                }

                g.String(data.v, Font, brush, data.rect, s_f);
            }
            else
            {
                g.Fill(brush2, new Rectangle(data.rect.X, data.rect_read.Y, data.rect.Width, data.rect_read.Height));
                if (DateNow.ToString("yyyy-MM-dd") == data.date_str)
                {
                    g.Draw(Style.Db.Primary, Config.Dpi, path);
                }

                g.String(data.v, Font, brush3, data.rect, s_f);
            }
        }
    }

    //
    // 摘要:
    //     渲染天模式
    //
    // 参数:
    //   g:
    //     GDI
    //
    //   rect_read:
    //     真实区域
    //
    //   datas:
    //     数据
    private void PrintDay(Canvas g, Rectangle rect_read, float radius, List<Calendari> datas)
    {
        if (rect_day_s == null)
        {
            return;
        }

        Color textBase = Style.Db.TextBase;
        using (Font font = new Font(Font.FontFamily, Font.Size, FontStyle.Bold))
        {
            string text = _Date.ToString(YearFormat, Culture);
            string text2 = _Date.ToString(MonthFormat, Culture);
            if (hover_year.Animation)
            {
                g.String(text, font, textBase.BlendColors(hover_year.Value, Style.Db.Primary), rect_year, s_f_L);
            }
            else if (hover_year.Switch)
            {
                g.String(text, font, Style.Db.Primary, rect_year, s_f_L);
            }
            else
            {
                g.String(text, font, textBase, rect_year, s_f_L);
            }

            if (hover_month.Animation)
            {
                g.String(text2, font, textBase.BlendColors(hover_month.Value, Style.Db.Primary), rect_month, s_f_R);
            }
            else if (hover_month.Switch)
            {
                g.String(text2, font, Style.Db.Primary, rect_month, s_f_R);
            }
            else
            {
                g.String(text2, font, textBase, rect_month, s_f_R);
            }
        }

        using (SolidBrush brush = new SolidBrush(Style.Db.Split))
        {
            g.Fill(brush, rect_day_split1);
            if (showButtonToDay)
            {
                g.Fill(brush, rect_day_split2);
            }
        }

        using (SolidBrush brush2 = new SolidBrush(Style.Db.Text))
        {
            g.String(MondayButton, Font, brush2, rect_day_s[0], s_f);
            g.String(TuesdayButton, Font, brush2, rect_day_s[1], s_f);
            g.String(WednesdayButton, Font, brush2, rect_day_s[2], s_f);
            g.String(ThursdayButton, Font, brush2, rect_day_s[3], s_f);
            g.String(FridayButton, Font, brush2, rect_day_s[4], s_f);
            g.String(SaturdayButton, Font, brush2, rect_day_s[5], s_f);
            g.String(SundayButton, Font, brush2, rect_day_s[6], s_f);
        }

        using SolidBrush solidBrush2 = new SolidBrush(textBase);
        using SolidBrush solidBrush3 = new SolidBrush(Style.Db.TextQuaternary);
        using SolidBrush brush5 = new SolidBrush(Style.Db.FillTertiary);
        using SolidBrush solidBrush = new SolidBrush(Style.Db.Primary);
        using SolidBrush brush3 = new SolidBrush(Style.Db.PrimaryColor);
        using (new SolidBrush(Style.Db.Error))
        {
            PaintToDayFrame(g, datas, DateNow.ToString("yyyy-MM-dd"), radius);
            if (chinese)
            {
                using Font font2 = new Font(Font.FontFamily, Font.Size * 0.76f, Font.Style);
                using SolidBrush brush4 = new SolidBrush(Style.Db.TextSecondary);
                foreach (Calendari data in datas)
                {
                    using GraphicsPath path = data.rect_read.RoundPath(radius);
                    ChineseDate chineseDate = ChineseDate.From(data.date);
                    if (_value.ToString("yyyy-MM-dd") == data.date_str)
                    {
                        g.Fill(solidBrush, path);
                        g.String(chineseDate.DayString, font2, brush3, data.rect_l, s_f);
                        g.String(data.v, Font, brush3, data.rect_f, s_f);
                    }
                    else if (data.enable)
                    {
                        if (data.hover)
                        {
                            g.Fill(Style.Db.FillTertiary, path);
                        }

                        g.String(chineseDate.DayString, font2, brush4, data.rect_l, s_f);
                        g.String(data.v, Font, (data.t == 1) ? solidBrush2 : solidBrush3, data.rect_f, s_f);
                    }
                    else
                    {
                        g.Fill(brush5, new Rectangle(data.rect.X, data.rect_read.Y, data.rect.Width, data.rect_read.Height));
                        g.String(chineseDate.DayString, font2, solidBrush3, data.rect_l, s_f);
                        g.String(data.v, Font, solidBrush3, data.rect_f, s_f);
                    }
                }
            }
            else
            {
                foreach (Calendari data2 in datas)
                {
                    using GraphicsPath path2 = data2.rect_read.RoundPath(radius);
                    if (_value.ToString("yyyy-MM-dd") == data2.date_str)
                    {
                        g.Fill(solidBrush, path2);
                        g.String(data2.v, Font, brush3, data2.rect, s_f);
                    }
                    else if (data2.enable)
                    {
                        if (data2.hover)
                        {
                            g.Fill(Style.Db.FillTertiary, path2);
                        }

                        g.String(data2.v, Font, (data2.t == 1) ? solidBrush2 : solidBrush3, data2.rect, s_f);
                    }
                    else
                    {
                        g.Fill(brush5, new Rectangle(data2.rect.X, data2.rect_read.Y, data2.rect.Width, data2.rect_read.Height));
                        g.String(data2.v, Font, solidBrush3, data2.rect, s_f);
                    }
                }
            }

            if (showButtonToDay)
            {
                if (hover_button.Animation)
                {
                    g.String(button_text, Font, solidBrush.Color.BlendColors(hover_button.Value, Style.Db.PrimaryActive), rect_button, s_f);
                }
                else if (hover_button.Switch)
                {
                    g.String(button_text, Font, Style.Db.PrimaryActive, rect_button, s_f);
                }
                else
                {
                    g.String(button_text, Font, solidBrush, rect_button, s_f);
                }
            }

            if (badge_list.Count <= 0)
            {
                return;
            }

            using Font font3 = new Font(Font.FontFamily, Font.Size * base.BadgeSize);
            foreach (Calendari data3 in datas)
            {
                if (badge_list.TryGetValue(data3.date_str, out DateBadgeEx value))
                {
                    this.PaintBadge(value, font3, data3.rect, g);
                }
            }
        }
    }

    //
    // 摘要:
    //     绘制今天边框
    internal static void PaintToDayFrame(Canvas g, IList<Calendari> datas, string dateNow, float radius)
    {
        foreach (Calendari data in datas)
        {
            if (dateNow == data.date_str)
            {
                using (GraphicsPath path = data.rect_read.RoundPath(radius))
                {
                    g.Draw(Style.Db.Primary, Config.Dpi, path);
                    break;
                }
            }
        }
    }

    protected override void OnMouseMove(MouseEventArgs e)
    {
        int num = 0;
        int num2 = 0;
        bool flag = rect_lefts.Contains(e.X, e.Y);
        bool flag2 = rect_rights.Contains(e.X, e.Y);
        bool flag3 = showType == 0 && rect_left.Contains(e.X, e.Y);
        bool flag4 = showType == 0 && rect_right.Contains(e.X, e.Y);
        bool flag5 = showType == 0 && showButtonToDay && rect_button.Contains(e.X, e.Y);
        bool flag6 = false;
        bool flag7 = false;
        if (showType != 2)
        {
            flag6 = ((showType == 0) ? rect_year.Contains(e.X, e.Y) : rect_year2.Contains(e.X, e.Y));
            flag7 = rect_month.Contains(e.X, e.Y);
        }

        if (flag != hover_lefts.Switch)
        {
            num++;
        }

        if (flag3 != hover_left.Switch)
        {
            num++;
        }

        if (flag2 != hover_rights.Switch)
        {
            num++;
        }

        if (flag4 != hover_right.Switch)
        {
            num++;
        }

        if (flag6 != hover_year.Switch)
        {
            num++;
        }

        if (flag7 != hover_month.Switch)
        {
            num++;
        }

        if (flag5 != hover_button.Switch)
        {
            num++;
        }

        hover_lefts.Switch = flag;
        hover_left.Switch = flag3;
        hover_rights.Switch = flag2;
        hover_right.Switch = flag4;
        hover_year.Switch = flag6;
        hover_month.Switch = flag7;
        hover_button.Switch = flag5;
        if (hover_lefts.Switch || hover_left.Switch || hover_rights.Switch || hover_right.Switch || hover_year.Switch || hover_month.Switch || hover_button.Switch)
        {
            num2++;
        }
        else if (showType == 1)
        {
            if (calendar_month != null)
            {
                foreach (Calendari item in calendar_month)
                {
                    bool flag8 = item.enable && item.rect.Contains(e.X, e.Y);
                    if (item.hover != flag8)
                    {
                        num++;
                    }

                    item.hover = flag8;
                    if (item.hover)
                    {
                        num2++;
                    }
                }
            }
        }
        else if (showType == 2)
        {
            if (calendar_year != null)
            {
                foreach (Calendari item2 in calendar_year)
                {
                    bool flag9 = item2.enable && item2.rect.Contains(e.X, e.Y);
                    if (item2.hover != flag9)
                    {
                        num++;
                    }

                    item2.hover = flag9;
                    if (item2.hover)
                    {
                        num2++;
                    }
                }
            }
        }
        else if (calendar_day != null)
        {
            foreach (Calendari item3 in calendar_day)
            {
                bool flag10 = item3.enable && item3.rect.Contains(e.X, e.Y);
                if (item3.hover != flag10)
                {
                    num++;
                }

                item3.hover = flag10;
                if (item3.hover)
                {
                    num2++;
                }
            }
        }

        if (num > 0)
        {
            Invalidate();
        }

        SetCursor(num2 > 0);
        base.OnMouseMove(e);
    }

    protected override void OnMouseLeave(EventArgs e)
    {
        hover_lefts.Switch = false;
        hover_left.Switch = false;
        hover_rights.Switch = false;
        hover_right.Switch = false;
        hover_year.Switch = false;
        hover_month.Switch = false;
        hover_button.Switch = false;
        if (calendar_year != null)
        {
            foreach (Calendari item in calendar_year)
            {
                item.hover = false;
            }
        }

        if (calendar_month != null)
        {
            foreach (Calendari item2 in calendar_month)
            {
                item2.hover = false;
            }
        }

        if (calendar_day != null)
        {
            foreach (Calendari item3 in calendar_day)
            {
                item3.hover = false;
            }
        }

        SetCursor(val: false);
        Invalidate();
        base.OnMouseLeave(e);
    }

    private void ChangeType(int type)
    {
        if (type != showType)
        {
            showType = type;
            OnSizeChanged(EventArgs.Empty);
            Invalidate();
        }
    }

    protected override void OnMouseUp(MouseEventArgs e)
    {
        if (e.Button == MouseButtons.Left)
        {
            if (rect_lefts.Contains(e.X, e.Y))
            {
                if (hover_lefts.Enable)
                {
                    if (showType == 2)
                    {
                        Date = _Date.AddYears(-10);
                    }
                    else
                    {
                        Date = _Date.AddYears(-1);
                    }

                    Invalidate();
                }

                return;
            }

            if (rect_rights.Contains(e.X, e.Y))
            {
                if (hover_rights.Enable)
                {
                    if (showType == 2)
                    {
                        Date = _Date.AddYears(10);
                    }
                    else
                    {
                        Date = _Date.AddYears(1);
                    }

                    Invalidate();
                }

                return;
            }

            if (showType == 0 && rect_left.Contains(e.X, e.Y))
            {
                if (hover_left.Enable)
                {
                    Date = _Date.AddMonths(-1);
                    Invalidate();
                }

                return;
            }

            if (showType == 0 && rect_right.Contains(e.X, e.Y))
            {
                if (hover_right.Enable)
                {
                    Date = _Date.AddMonths(1);
                    Invalidate();
                }

                return;
            }

            if ((showType == 0 && rect_year.Contains(e.X, e.Y)) || (showType != 0 && rect_year2.Contains(e.X, e.Y)))
            {
                ChangeType(2);
                return;
            }

            if (showType == 0 && showButtonToDay && rect_button.Contains(e.X, e.Y))
            {
                DateTime value = (Date = (DateNow = DateTime.Now));
                Value = value;
                return;
            }

            if (rect_month.Contains(e.X, e.Y))
            {
                ChangeType(1);
                return;
            }

            if (showType == 1)
            {
                if (calendar_month != null)
                {
                    foreach (Calendari item in calendar_month)
                    {
                        if (item.enable && item.rect.Contains(e.X, e.Y))
                        {
                            Date = item.date;
                            ChangeType(0);
                            return;
                        }
                    }
                }
            }
            else if (showType == 2)
            {
                if (calendar_year != null)
                {
                    foreach (Calendari item2 in calendar_year)
                    {
                        if (item2.enable && item2.rect.Contains(e.X, e.Y))
                        {
                            Date = item2.date;
                            ChangeType(1);
                            return;
                        }
                    }
                }
            }
            else if (calendar_day != null)
            {
                foreach (Calendari item3 in calendar_day)
                {
                    if (item3.enable && item3.rect.Contains(e.X, e.Y))
                    {
                        Value = item3.date;
                        return;
                    }
                }
            }
        }

        base.OnMouseUp(e);
    }

    protected override void OnMouseWheel(MouseEventArgs e)
    {
        if (e.Delta != 0)
        {
            MouseWheelDay(e);
        }

        base.OnMouseWheel(e);
    }

    private void MouseWheelDay(MouseEventArgs e)
    {
        if (e.Delta > 0)
        {
            if (showType == 1)
            {
                if (!hover_lefts.Enable)
                {
                    return;
                }

                Date = _Date.AddYears(-1);
            }
            else if (showType == 2)
            {
                if (!hover_lefts.Enable)
                {
                    return;
                }

                Date = _Date.AddYears(-10);
            }
            else
            {
                if (!hover_left.Enable)
                {
                    return;
                }

                Date = _Date.AddMonths(-1);
            }

            Invalidate();
            return;
        }

        if (showType == 1)
        {
            if (!hover_rights.Enable)
            {
                return;
            }

            Date = _Date.AddYears(1);
        }
        else if (showType == 2)
        {
            if (!hover_rights.Enable)
            {
                return;
            }

            Date = _Date.AddYears(10);
        }
        else
        {
            if (!hover_right.Enable)
            {
                return;
            }

            Date = _Date.AddMonths(1);
        }

        Invalidate();
    }

    protected override void OnSizeChanged(EventArgs e)
    {
        float dpi = Config.Dpi;
        Rectangle readRectangle = ReadRectangle;
        int num = 34;
        int num2 = (showButtonToDay ? 38 : 0);
        int num3 = 60;
        int num4 = 88;
        int num5 = 40;
        if (dpi != 1f)
        {
            num = (int)((float)num * dpi);
            if (showButtonToDay)
            {
                num2 = (int)((float)num2 * dpi);
            }

            num3 = (int)((float)num3 * dpi);
            num4 = (int)((float)num4 * dpi);
            num5 = (int)((float)num5 * dpi);
        }

        rect_lefts = new Rectangle(readRectangle.X, readRectangle.Y, num, num);
        rect_left = new Rectangle(readRectangle.X + num, readRectangle.Y, num, num);
        rect_rights = new Rectangle(readRectangle.X + readRectangle.Width - num, readRectangle.Y, num, num);
        rect_right = new Rectangle(readRectangle.X + readRectangle.Width - num * 2, readRectangle.Y, num, num);
        int num6 = (int)(4f * Config.Dpi);
        int num7 = readRectangle.Width / 2;
        rect_year2 = new Rectangle(readRectangle.X + (readRectangle.Width - num4) / 2, readRectangle.Y, num4, num);
        rect_button = new Rectangle(readRectangle.X, readRectangle.Bottom - num2, readRectangle.Width, num2);
        if (YDR)
        {
            rect_month = new Rectangle(readRectangle.X + num7 - num3 - num6, readRectangle.Y, num3, num);
            rect_year = new Rectangle(readRectangle.X + num7 + num6, readRectangle.Y, num5, num);
        }
        else
        {
            rect_year = new Rectangle(readRectangle.X + num7 - num3 - num6, readRectangle.Y, num3, num);
            rect_month = new Rectangle(readRectangle.X + num7 + num6, readRectangle.Y, num5, num);
        }

        int num8 = (int)(8f * dpi);
        int num9 = num8 * 2;
        if (showType == 1)
        {
            rect_month_l = new Rectangle(readRectangle.X, readRectangle.Y, readRectangle.Width, num);
            int num10 = readRectangle.Y + num;
            int num11 = (readRectangle.Width - num9) / 3;
            int num12 = (readRectangle.Height - num - num9) / 4;
            if (calendar_month != null)
            {
                foreach (Calendari item in calendar_month)
                {
                    item.rect = new Rectangle(readRectangle.X + num8 + num11 * item.x, num10 + num8 + num12 * item.y, num11, num12);
                }
            }
        }
        else if (showType == 2)
        {
            rect_year_l = new Rectangle(readRectangle.X, readRectangle.Y, readRectangle.Width, num);
            int num13 = readRectangle.Y + num;
            int num14 = (readRectangle.Width - num9) / 3;
            int num15 = (readRectangle.Height - num - num9) / 4;
            if (calendar_year != null)
            {
                foreach (Calendari item2 in calendar_year)
                {
                    item2.rect = new Rectangle(readRectangle.X + num8 + num14 * item2.x, num13 + num8 + num15 * item2.y, num14, num15);
                }
            }
        }
        else if (chinese)
        {
            int num16 = readRectangle.Y + num + 12;
            int num17 = (readRectangle.Width - num9) / 7;
            int num18 = (readRectangle.Height - num - num2 - num9) / 7;
            rect_day_split1 = new RectangleF(readRectangle.X, readRectangle.Y + num, readRectangle.Width, Config.Dpi);
            if (showButtonToDay)
            {
                rect_day_split2 = new RectangleF(readRectangle.X, (float)rect_button.Y - 0.5f, readRectangle.Width, Config.Dpi);
            }

            rect_day_s = new Rectangle[7]
            {
                new Rectangle(readRectangle.X + num8, num16, num17, num18),
                new Rectangle(readRectangle.X + num8 + num17, num16, num17, num18),
                new Rectangle(readRectangle.X + num8 + num17 * 2, num16, num17, num18),
                new Rectangle(readRectangle.X + num8 + num17 * 3, num16, num17, num18),
                new Rectangle(readRectangle.X + num8 + num17 * 4, num16, num17, num18),
                new Rectangle(readRectangle.X + num8 + num17 * 5, num16, num17, num18),
                new Rectangle(readRectangle.X + num8 + num17 * 6, num16, num17, num18)
            };
            num16 += num18;
            if (calendar_day != null)
            {
                foreach (Calendari item3 in calendar_day)
                {
                    item3.SetRectG(new Rectangle(readRectangle.X + num8 + num17 * item3.x, num16 + num18 * item3.y, num17, num18), 0.92f);
                    item3.rect_f = new Rectangle(item3.rect_read.X, item3.rect_read.Y, item3.rect_read.Width, item3.rect_read.Height - item3.rect_read.Height / 4);
                    item3.rect_l = new Rectangle(item3.rect_read.X, item3.rect_read.Y + item3.rect_read.Height / 2, item3.rect_read.Width, item3.rect_read.Height / 2);
                }
            }
        }
        else if (full)
        {
            int num19 = readRectangle.Y + num + 12;
            int num20 = (readRectangle.Width - num9) / 7;
            int num21 = (readRectangle.Height - num - num2 - num9) / 7;
            rect_day_split1 = new RectangleF(readRectangle.X, readRectangle.Y + num, readRectangle.Width, Config.Dpi);
            if (showButtonToDay)
            {
                rect_day_split2 = new RectangleF(readRectangle.X, (float)rect_button.Y - 0.5f, readRectangle.Width, Config.Dpi);
            }

            rect_day_s = new Rectangle[7]
            {
                new Rectangle(readRectangle.X + num8, num19, num20, num21),
                new Rectangle(readRectangle.X + num8 + num20, num19, num20, num21),
                new Rectangle(readRectangle.X + num8 + num20 * 2, num19, num20, num21),
                new Rectangle(readRectangle.X + num8 + num20 * 3, num19, num20, num21),
                new Rectangle(readRectangle.X + num8 + num20 * 4, num19, num20, num21),
                new Rectangle(readRectangle.X + num8 + num20 * 5, num19, num20, num21),
                new Rectangle(readRectangle.X + num8 + num20 * 6, num19, num20, num21)
            };
            num19 += num21;
            if (calendar_day != null)
            {
                foreach (Calendari item4 in calendar_day)
                {
                    item4.SetRectG(new Rectangle(readRectangle.X + num8 + num20 * item4.x, num19 + num21 * item4.y, num20, num21), 0.92f);
                }
            }
        }
        else
        {
            int num22 = readRectangle.Y + num + 12;
            int num23 = (readRectangle.Width - num9) / 7;
            int num24 = (readRectangle.Height - num - num2 - num9) / 7;
            int num25 = num23;
            if (num23 > num24)
            {
                num25 = num24;
                num9 = readRectangle.Width - num25 * 7;
                num8 = num9 / 2;
            }

            rect_day_split1 = new RectangleF(readRectangle.X, readRectangle.Y + num, readRectangle.Width, Config.Dpi);
            if (showButtonToDay)
            {
                rect_day_split2 = new RectangleF(readRectangle.X, (float)rect_button.Y - 0.5f, readRectangle.Width, Config.Dpi);
            }

            rect_day_s = new Rectangle[7]
            {
                new Rectangle(readRectangle.X + num8, num22, num25, num25),
                new Rectangle(readRectangle.X + num8 + num25, num22, num25, num25),
                new Rectangle(readRectangle.X + num8 + num25 * 2, num22, num25, num25),
                new Rectangle(readRectangle.X + num8 + num25 * 3, num22, num25, num25),
                new Rectangle(readRectangle.X + num8 + num25 * 4, num22, num25, num25),
                new Rectangle(readRectangle.X + num8 + num25 * 5, num22, num25, num25),
                new Rectangle(readRectangle.X + num8 + num25 * 6, num22, num25, num25)
            };
            num22 += num25;
            if (calendar_day != null)
            {
                int gap = (int)((float)num25 * 0.666f);
                foreach (Calendari item5 in calendar_day)
                {
                    item5.SetRect(new Rectangle(readRectangle.X + num8 + num25 * item5.x, num22 + num25 * item5.y, num25, num25), gap);
                }
            }
        }

        base.OnSizeChanged(e);
    }

    protected override void Dispose(bool disposing)
    {
        hover_lefts?.Dispose();
        hover_left?.Dispose();
        hover_rights?.Dispose();
        hover_right?.Dispose();
        hover_year?.Dispose();
        hover_month?.Dispose();
        hover_button?.Dispose();
        base.Dispose(disposing);
    }
}


internal class Calendari
{
    private Rectangle _rect;

    public Rectangle rect_read;

    public Rectangle rect_f;

    public Rectangle rect_l;

    public bool hover { get; set; }

    public Rectangle rect
    {
        get
        {
            return _rect;
        }
        set
        {
            rect_read = new Rectangle(value.X + 4, value.Y + 4, value.Width - 8, value.Height - 8);
            _rect = value;
        }
    }

    public int x { get; set; }

    public int y { get; set; }

    public int t { get; set; }

    public string v { get; set; }

    public DateTime date { get; set; }

    public string date_str { get; set; }

    public bool enable { get; set; }

    public Calendari(int _t, int _x, int _y, string _v, DateTime _date, string str, DateTime? min, DateTime? max)
    {
        t = _t;
        x = _x;
        y = _y;
        v = _v;
        date = _date;
        date_str = str;
        enable = Helper.DateExceedRelax(_date, min, max);
    }

    public Calendari(int _t, int _x, int _y, string _v, DateTime _date, DateTime? min, DateTime? max)
    {
        t = _t;
        x = _x;
        y = _y;
        v = _v;
        date = _date;
        date_str = _date.ToString("yyyy-MM-dd");
        enable = Helper.DateExceed(_date, min, max);
    }

    internal void SetRect(Rectangle value, int gap)
    {
        int num = (value.Width - gap) / 2;
        rect_read = new Rectangle(value.X + num, value.Y + num, gap, gap);
        _rect = value;
    }

    internal void SetRectG(Rectangle value, float gap)
    {
        int num = (int)((float)value.Width * gap);
        int num2 = (int)((float)value.Height * gap);
        rect_read = new Rectangle(value.X + (value.Width - num) / 2, value.Y + (value.Height - num2) / 2, num, num2);
        _rect = value;
    }
}